<?php

/**
 * Copyright (C) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     @license http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

$currentDir = dirname(__FILE__);
/*require_once($currentDir . "/utilities.php");*/
require_once($currentDir . "/sensapilityaccount.php");
require_once($currentDir . "/sensapilitychannel.php");
require_once($currentDir . "/sensapilityafc.php");
require_once($currentDir . "/sensapilityafs.php");
require_once($currentDir . "/sensapilitysitefilter.php");
require_once($currentDir . "/sensapilityreport.php");

/**
 * @author api.jmatt@gmail.com, api.wes@gmail.com
 * @version 0.2
 */
class SensapilityClients {
  /**
   * @access private
   * @var array an array of SensAPIlity wrapper objects for API services
   */
  var $clients;
    /**
   * @access private
   * @var array an array of XML string fragments, this array will be accessed
   * when the wrapper object is built
   */
  var $headers;
  /**
   * @access private
   * @var array an array of strings, which when combined with 
   * $_baseServiceLocale provides the complete URL for the service
   */
  var $_serviceLocations;
  /**
   * @access private
   * @var string the base URL for where the services are located, set by the 
   * constructor
   */
  var $_baseServiceLocale;
    /**
   * @access private
   * @var array associative array of strings mapping from namespace names to
   * namespace values, these namespaces are then put in the SOAP envelope
   */
  var $namespaces;
  /**
   * @access private
   * @var string the default namespace label used for header tags
   */
  var $namespaceLabel = "ns1";
  
  /**
   * Constructor for this class, creates 
   * @param string $serverAddress the address where the AdSense API 
   * service is
   * @return mixed a new SensapilityClients object
   */
  function SensapilityClients($serverAddress = 
                              'https://www.google.com/api/adsense/v3/') {
    $this->_baseServiceLocale = $serverAddress;
    
    // init the _serviceLocations array
    $this->_serviceLocations = array();
    $this->_serviceLocations['Account'] = 'AccountService';
    $this->_serviceLocations['Report'] = 'ReportService';
    $this->_serviceLocations['AdSenseForContent'] = 'AdSenseForContentService';
    $this->_serviceLocations['AdSenseForSearch'] = 'AdSenseForSearchService';
    $this->_serviceLocations['Referral'] = 'ReferralService';
    $this->_serviceLocations['SiteFilter'] = 'SiteFilterService';
    $this->_serviceLocations['Channel'] = 'ChannelService';
    
    // init the clients and headers arrays to be empty
    $this->headers = array();
    $this->clients = array();
    $keys = array_keys($this->_serviceLocations);
    foreach ( $keys as $key ) {
      $this->headers[$key] = null;
      $this->clients[$key] = null;
    }
    
    // set the namespaces we'll use
    $this->namespaces = array();
    $this->namespaces[$this->namespaceLabel] = 
        'http://www.google.com/api/adsense/v3';
    $this->namespaces['SOAP-ENV'] = 'http://schemas.xmlsoap.org/soap/envelope/';
  }
  
  /**
   * Sets headers for the requested service
   * @param string $serviceName the name of the service to set headers for
   * @param string $header the XML string value for the header
   * @return none
   */
  function setHeaders($serviceName, $header) {
    if ( array_key_exists($serviceName, $this->headers) ) {
      $this->headers[$serviceName] = $header;
      if ( !is_null($this->clients[$serviceName]) ) {
        $this->clients[$serviceName]->setHeaders($this->headers[$serviceName]);
      }
    }
  }
  
  /**
   * Returns the SensAPIlity wrapper object for the requested service.
   * @param string $serviceName the name of the service to requested
   * @return SensapilityService the object wrapper for the requested service
   */
  function getService($serviceName) {
    if ( array_key_exists($serviceName, $this->clients) ) {
      // check if the service object is constructed
      if ( is_null($this->clients[$serviceName]) ) {
        $this->_buildSOAPClient($serviceName);
      }
      return $this->clients[$serviceName];
    } else {
      echo 'SensAPIlity PHP library: SensapilityClients::getService, ' . 
           'requested service name not recognized.\n';
      return 0;
    }
  }
  
  /**
   * Constructs the underlying soapclientnusoap object for this service
   * @param string $serviceName name of the service to build the wrapper 
   * object for
   * @return none
   */
  function _buildSOAPClient($serviceName) {
    
    // load the service
    $serviceURL = $this->_baseServiceLocale .
                      $this->_serviceLocations[$serviceName];
    $serviceObject = new soapclientNusoap($serviceURL, true);
    
    // note that the headers may be null, which is fine, we'll just issue a
    // warning
    if ( is_null($this->headers[$serviceName]) ) {
      echo 'SensAPIlity PHP library: SensapilityClients::getService, ' .
           'header for requested service is not set, the service may not ' .
           "function properly.\n";
    }
    $serviceObject->setHeaders($this->headers[$serviceName]);
    
    // switch block to call the right class
    switch ( $serviceName ) {
    case 'Account':
      $this->clients[$serviceName] = 
          new SensapilityAccount($serviceObject, 
                                 $this->namespaces, 
                                 $this->namespaceLabel);
      break;
    case 'Report':
      $this->clients[$serviceName] = 
          new SensapilityReport($serviceObject, 
                                $this->namespaces, 
                                $this->namespaceLabel);
      break;
    case 'AdSenseForContent':
      $this->clients[$serviceName] = 
          new SensapilityAfc($serviceObject, 
                             $this->namespaces, 
                             $this->namespaceLabel);
      break;
    case 'AdSenseForSearch':
      $this->clients[$serviceName] = 
          new SensapilityAfs($serviceObject, 
                             $this->namespaces, 
                             $this->namespaceLabel);
      break;
    case 'Referral':
      $this->clients[$serviceName] = 
          new SensapilityReferral($serviceObject, 
                                  $this->namespaces, 
                                  $this->namespaceLabel);
      break;
    case 'SiteFilter':
      $this->clients[$serviceName] = 
          new SensapilitySiteFilter($serviceObject, 
                                    $this->namespaces, 
                                    $this->namespaceLabel);
      break;
    case 'Channel':
      $this->clients[$serviceName] = 
          new SensapilityChannel($serviceObject, 
                                 $this->namespaces, 
                                 $this->namespaceLabel);
      break;
    }
  }

  /**
   * Changes the address where services are accessed
   * @param string $serverAddr the address where the services are located
   * @return none
   */
  function setServerAddress($serverAddr) {
    $this->_baseServiceLocale = $serverAddr;
  }

  /**
   * Gets the current address where services are accessed
   * @return string the current address we're using for services
   */
  function getServerAddress() {
    return $this->_baseServiceLocale;
  }
}
?>
